import { ElementIdentifier } from './element/service/element_identifier'
import { LogStyle } from './lib/logger'
import { ConfigManager } from './module/config_manager'
import {
  AppModule,
  MODULE_CONSTRUCTORS,
} from './module/config_manager/types'
import { ModuleManager } from './module/module_manager'
import { AdEngine } from './module/page_enhancer/appearance/ad_control'
import { TocEngine } from './module/page_enhancer/appearance/article_toc'
import { StyleEnhancement } from './module/page_enhancer/appearance/style_enhancement'
import { ALL_PLATFORM_STYLES } from './module/page_enhancer/appearance/style_enhancement/platforms'
import { ElementAdapt } from './module/page_enhancer/base/element_adapt'
import { StyleManager } from './module/style_manager'
import { HOSTNAME, logger } from './types/constants'
import { SYMBOLS } from './types/interfaces'

export class AppLoader {
  private readonly name: string = 'AppLoader'

  constructor() {
    this.setupEnvironment()
    this.setupPlatformStyles()
    this.setUpModuleStyles()
  }

  async bootstrap(): Promise<void> {
    try {
      await logger.executeWithLogging('网页功能', async () => {
        await this.registerFeatureModules()
      }, {
        collapsed: false,
        color: LogStyle.groupHeader,
      })
      logger.important(`[${this.name}] ${SYMBOLS.STATUS.SUCCESS} 服务加载完成`)
    }
    catch (error: any) {
      logger.error(`[${this.name}] ${SYMBOLS.STATUS.ERROR} 服务加载失败`, error)
    }
  }

  /**
   * 设置环境
   */
  private setupEnvironment() {
    // 1. 初始化元素标识符
    const elementIdentifier = ElementIdentifier.getInstance()
    elementIdentifier.init()
    logger.important(`[${this.name}] ${SYMBOLS.TOOLS.WRENCH} 元素标识符加载完成`, elementIdentifier.api.getStats())
  }

  /**
   * 初始化平台样式
   */
  private setupPlatformStyles() {
    // 初始化样式管理器
    const styleEnhancement = StyleEnhancement.getInstance()

    // 注册平台样式
    Object.entries(ALL_PLATFORM_STYLES).forEach(([platform, StyleClass]) => {
      if (HOSTNAME === platform) {
        styleEnhancement.registerPlatform(platform, StyleClass.getInstance().getStyles())
      }
    })
  }

  /**
   * 初始化模块样式
   */
  private setUpModuleStyles() {
    const styleManager = StyleManager.getInstance()
    const stylesMap = new Map()

    styleManager.batchRegisterStyles(stylesMap)
  }

  /**
   * 加载模块功能
   */
  private async registerFeatureModules() {
    // 1. 初始化模块管理器
    const configManager = ConfigManager.getInstance()
    const moduleManager = ModuleManager.getInstance()

    // 2. 注册'基础'模块（功能模块会依赖）
    const elementAdapt = new ElementAdapt()
    elementAdapt.init()
    logger.important(`[${this.name}] 页面元素已适配完成`)

    // 3. 注册'功能开关'模块
    const moduleNames = configManager.getPlatformModules()
      .flatMap((item) => {
        const entry = Object.values(AppModule)
          .find(meta => meta.id === item.id)

        return entry ? [entry.className] : []
      })
      .filter(Boolean) // 确保最终结果不含空值

    // 按顺序注册模块
    MODULE_CONSTRUCTORS.forEach((item) => {
      moduleManager.registerModule(item.constructor())
    })

    // 检测无效的模块名称
    let invalidModuleNames = moduleNames.filter((moduleName: string) => !Object.values(AppModule).map(meta => meta.className).includes(moduleName))
    // ！！！特殊处理：去掉自定义元素的模块
    const modulesToRemove = ['TocEngine', 'AdEngine']
    invalidModuleNames = invalidModuleNames.filter(name => !modulesToRemove.includes(name))
    if (invalidModuleNames.length > 0) {
      logger.error(`[${this.name}] 'moduleFeatureMap' 中存在未定义的模块标识: ${invalidModuleNames.join('、')}`)
    }

    // 4. 注册'自定义元素'模块
    moduleManager.registerModule(TocEngine.getInstance())
    moduleManager.registerModule(AdEngine.getInstance()) // 必须在 ElementHider 元素隐藏之后，因为会涉及元素显示判断

    // 5. 初始化模块
    await moduleManager.initModules()
    logger.info(`[${this.name}] ${SYMBOLS.STATUS.SUCCESS} 模块加载完成`)

    // 6. 自动绑定配置
    configManager.autoRegisterModules(moduleManager)

    // 7. 页面卸载时清理
    window.addEventListener('unload', () => {
      moduleManager.destroyModules().catch(console.error)
    })
  }
}
